﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _5._02使用await操作符获取异步任务结果
{
    class Program
    {
        /// <summary>
        /// 调用async方法会有显著的性能损失，通常的方法调用比使用async关键字的同样方法调用要快上40-50倍
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Task t = AsynchronyWithTPL();
            t.Wait();

            t = AsynchronyWithAwait();
            t.Wait();

            Console.ReadLine();
        }

        static Task AsynchronyWithTPL()
        {
            Task<string> t = GetInfoAsync("Task 1");
            Task t2 = t.ContinueWith(task => Console.WriteLine(t.Result), TaskContinuationOptions.NotOnFaulted);
            Task t3 = t.ContinueWith(task => Console.WriteLine(t.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted);
            return Task.WhenAny(t2, t3);
        }

        /// <summary>
        /// 使用await后，C#立即创建了一个任务，其有一个后续操作任务，包含了await操作符后面的所有剩余代码
        /// 这个新任务也处理了异常传播，然后，将任务返回到主方法中并等待其完成
        /// </summary>
        /// <returns></returns>
        async static Task AsynchronyWithAwait()
        {
            try
            {
                string result = await GetInfoAsync("Task 2");
                Console.WriteLine($"外部执行时间：{DateTime.Now}");
                Console.WriteLine(result);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        private async static Task<string> GetInfoAsync(string name)
        {
            await Task.Delay(TimeSpan.FromSeconds(2));
            //throw new Exception("Boom!");
            Console.WriteLine($"内部执行时间：{DateTime.Now}");
            return $"Task {name} is running on a thread id {Thread.CurrentThread.ManagedThreadId}, Is thread pool thread: {Thread.CurrentThread.IsThreadPoolThread}";
        }
    }
}
